home *** CD-ROM | disk | FTP | other *** search
/ Aminet 52 / Aminet 52 (2002)(GTI - Schatztruhe)[!][Dec 2002].iso / Aminet / dev / gg / gengetopt-2.6.lha / gengetopt-2.6 / src / gm.c < prev    next >
C/C++ Source or Header  |  2002-03-02  |  25KB  |  983 lines

  1. /**
  2.  * Copyright (C) 1999, 2000, 2001  Free Software Foundation, Inc.
  3.  *
  4.  * This file is part of GNU gengetopt 
  5.  *
  6.  * GNU gengetopt is free software; you can redistribute it and/or modify 
  7.  * it under the terms of the GNU General Public License as published by 
  8.  * the Free Software Foundation; either version 2, or (at your option) 
  9.  * any later version. 
  10.  *
  11.  * GNU gengetopt is distributed in the hope that it will be useful, but 
  12.  * WITHOUT ANY WARRANTY; without even the implied warranty of 
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
  14.  * Public License for more details. 
  15.  *
  16.  * You should have received a copy of the GNU General Public License along 
  17.  * with gengetopt; see the file COPYING. If not, write to the Free Software 
  18.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
  19.  */
  20.  
  21. #include <stdlib.h>
  22. #include <stdio.h>
  23. #include <string.h>
  24.  
  25. #include "argsdef.h"
  26. #include "ggos.h"
  27. #include "gm.h"
  28.  
  29. #define TAB_LEN 2
  30.  
  31. extern struct gengetopt_option * gengetopt_options;
  32. extern char * gengetopt_package;
  33. extern char * gengetopt_version;
  34. extern char * gengetopt_purpose;
  35. extern int gengetopt_strdup_text_length;
  36. extern char *gengetopt_strdup_text[];
  37.  
  38. static int tab_indentation ; /* tab indentation level */
  39. static int handle_error; /* should I handle errors, by exit(1) */
  40.  
  41. static char *create_filename (char *name, char *ext);
  42. static FILE *open_outputfile (char *filename);
  43. static void indent() ;
  44. static void inc_indent() ;
  45. static void dec_indent() ;
  46. static void check_option_given( char *var_arg,
  47.                                 char *long_opt, char short_opt ) ;
  48. static void generate_error_handle();
  49. static char *canonize_names(char * name);
  50.  
  51. #define ARGS_STRUCT "args_info"
  52. #define ARGS_STRUCT_NAME PACKAGE "_" ARGS_STRUCT
  53.  
  54. static char *parser_function_name;
  55.  
  56. char *
  57. create_filename (char *name, char *ext)
  58. {
  59.   char *filename ;
  60.  
  61.   filename = (char *) malloc (strlen (name) + strlen (ext) + 2);
  62.   /* 2 = 1 for the . and one for the '\0' */
  63.   if (! filename)
  64.     {
  65.       fprintf (stderr, "Error in memory allocation! %s %d\n",
  66.                __FILE__, __LINE__);
  67.       abort ();
  68.     }
  69.  
  70.   sprintf (filename, "%s.%s", name, ext);
  71.  
  72.   return filename ;
  73. }
  74.  
  75. FILE *
  76. open_outputfile (char *filename)
  77. {
  78.   FILE *output_file ;
  79.   
  80.   output_file = freopen ( filename, "w", stdout ) ;
  81.   if ( ! output_file )
  82.     {
  83.       fprintf( stderr, "Error creating %s\n", filename ) ;
  84.       abort() ;
  85.     }
  86.  
  87.   return output_file;
  88. }
  89.  
  90. static void
  91. do_check_option_given (struct gengetopt_option *opt)
  92. {
  93.     switch (opt->type) {
  94.     case ARG_NO:
  95.         check_option_given (opt->var_arg, opt->long_opt, opt->short_opt);
  96.         break;
  97.     case ARG_FLAG:
  98.         check_option_given (opt->var_arg, opt->long_opt, opt->short_opt);
  99.         indent ();
  100.         printf ("%s->%s_flag = !(%s->%s_flag);\n",
  101.                 ARGS_STRUCT,
  102.                 opt->var_arg,
  103.                 ARGS_STRUCT,
  104.                 opt->var_arg);
  105.         break;
  106.     case ARG_STRING:
  107.         check_option_given (opt->var_arg, opt->long_opt, opt->short_opt);
  108.         indent ();
  109.         printf ("%s->%s_arg = strdup (optarg);\n",
  110.                 ARGS_STRUCT, opt->var_arg);
  111.         break;
  112.     case ARG_INT:
  113.         check_option_given (opt->var_arg, opt->long_opt, opt->short_opt);
  114.         indent ();
  115.         printf ("%s->%s_arg = atoi (optarg);\n",
  116.                 ARGS_STRUCT, opt->var_arg);
  117.         break;
  118.     case ARG_SHORT:
  119.         check_option_given (opt->var_arg, opt->long_opt, opt->short_opt);
  120.         indent ();
  121.         printf ("%s->%s_arg = (short)atoi (optarg);\n",
  122.                 ARGS_STRUCT, opt->var_arg);
  123.         break;
  124.     case ARG_LONG:
  125.         check_option_given (opt->var_arg, opt->long_opt, opt->short_opt);
  126.         indent ();
  127.         printf ("%s->%s_arg = atol (optarg);\n", 
  128.                 ARGS_STRUCT, opt->var_arg);
  129.         break;
  130.     case ARG_FLOAT:
  131.         check_option_given (opt->var_arg, opt->long_opt, opt->short_opt);
  132.         indent ();
  133.         printf ("%s->%s_arg = (float)strtod (optarg, NULL);\n",
  134.                 ARGS_STRUCT, opt->var_arg);
  135.         break;
  136.     case ARG_DOUBLE:
  137.         check_option_given (opt->var_arg, opt->long_opt, opt->short_opt);
  138.         indent ();
  139.         printf ("%s->%s_arg = strtod (optarg, NULL);\n",
  140.                 ARGS_STRUCT, opt->var_arg);
  141.         break;
  142.     case ARG_LONGDOUBLE:
  143.         check_option_given (opt->var_arg, opt->long_opt, opt->short_opt);
  144.         indent ();
  145.         printf ("%s->%s_arg = (long double) strtod (optarg, NULL);\n",
  146.                 ARGS_STRUCT, opt->var_arg);
  147.         break;
  148.     case ARG_LONGLONG:
  149.         check_option_given (opt->var_arg, opt->long_opt, opt->short_opt);
  150.         indent ();
  151.         printf ("%s->%s_arg = (long long)atol (optarg);\n",
  152.                 ARGS_STRUCT, opt->var_arg);
  153.         break;
  154.     default:
  155.         fprintf (stderr, "gengetopt: bug found in %s:%d\n", __FILE__,
  156.                  __LINE__);
  157.         abort ();
  158.     }
  159. }
  160.  
  161. int
  162. generate_cmdline_parser (char *function_name, short unamed_options,
  163.                          char *filename, char *header_ext, char *c_ext,
  164.                          int long_help, int no_handle_help,
  165.                          int no_handle_version,
  166.                          int no_handle_error, char **comment)
  167. {
  168.   long max_long, max_short, w;
  169.   struct gengetopt_option * opt;
  170.   char *comment_string ;
  171.   int i ;
  172.   int first_time = 1;
  173.   
  174.   short generate_strdup = unamed_options;
  175.   /* if unamed_options is specified gengetopt_strdup has to be generated;
  176.      otherwise it will be only if a string option is specified */
  177.  
  178.   FILE *output_file ;
  179.  
  180.   char *filename_canonized = 0;
  181.  
  182.   char *header_filename ;
  183.   char *c_filename ;
  184.   parser_function_name = canonize_names (function_name); 
  185.   /* initialize static data */
  186.  
  187.   header_filename = create_filename (filename, header_ext) ;
  188.   c_filename = create_filename (filename, c_ext) ;
  189.  
  190.   /* global static fields */
  191.   tab_indentation = 0;
  192.   handle_error = (! no_handle_error);
  193.  
  194. # define foropt for (opt = gengetopt_options;             \
  195.              opt != (struct gengetopt_option *)0; \
  196.              opt=opt->next)
  197.  
  198.   if (gengetopt_options == (struct gengetopt_option *)0) {
  199.     fprintf (stderr, "gengetopt: none option given\n");
  200.     return 1;
  201.   }
  202.  
  203.   /* ****************************************************** */
  204.   /* HEADER FILE******************************************* */
  205.   /* ****************************************************** */
  206.  
  207.   output_file = open_outputfile (header_filename);
  208.  
  209.   printf ("/* %s */\n\n", header_filename);
  210.   printf ("/* File autogenerated by gengetopt version %s  */\n\n",
  211.           VERSION) ;
  212.  
  213.   filename_canonized = canonize_names (filename);
  214.   printf ("#ifndef _%s_%s\n", filename_canonized, header_ext);
  215.   printf ("#define _%s_%s\n\n", filename_canonized, header_ext);
  216.  
  217.   printf ("#ifdef __cplusplus\n");
  218.   printf ("extern \"C\" {\n");
  219.   printf ("#endif /* __cplusplus */\n");
  220.  
  221.   printf ("\n/* Don't define PACKAGE and VERSION if we use automake.  */\n");
  222.  
  223.   if (gengetopt_package != NULL)
  224.     printf (""
  225. "#if defined PACKAGE\n"
  226. "#  undef PACKAGE\n"
  227. "#endif\n"
  228. "#define PACKAGE \"%s\"\n", gengetopt_package);
  229.   else
  230.     printf (""
  231. "#ifndef PACKAGE\n"
  232. "/* ******* WRITE THE NAME OF YOUR PROGRAM HERE ******* */\n"
  233. "#define PACKAGE \"\"\n"
  234. "#endif\n");
  235.  
  236.   if (gengetopt_version != NULL)
  237.     printf (""
  238. "#if defined VERSION\n"
  239. "#  undef VERSION\n"
  240. "#endif\n"
  241. "#define VERSION \"%s\"\n", gengetopt_version);
  242.   else
  243.     printf (""
  244. "#ifndef VERSION\n"
  245. "/* ******* WRITE THE VERSION OF YOUR PROGRAM HERE ******* */\n"
  246. "#define VERSION \"\"\n"
  247. "#endif\n");
  248.  
  249.   /* ****************************************************** */
  250.   /* *********************************  HEADER   STRUCTURES */
  251.   /* ****************************************************** */
  252.  
  253.   printf ("\nstruct %s {\n", ARGS_STRUCT_NAME ) ;
  254.   inc_indent ();
  255.  
  256.   foropt
  257.     if (opt->type != ARG_NO) {
  258.         switch (opt->type) {
  259.         case ARG_FLAG:
  260.         case ARG_STRING:
  261.         case ARG_INT:
  262.         case ARG_SHORT:
  263.         case ARG_LONG:
  264.         case ARG_FLOAT:
  265.         case ARG_DOUBLE:
  266.         case ARG_LONGDOUBLE:
  267.         case ARG_LONGLONG:
  268.                   indent ();
  269.                   printf ("%s ", arg_types[opt->type]);
  270.                   break;
  271.         default: fprintf (stderr, "gengetopt: bug found in %s:%d!!\n",
  272.                   __FILE__, __LINE__);
  273.              abort ();
  274.         }
  275.  
  276.                 if (opt->type == ARG_FLAG)
  277.              printf ("%s_flag", opt->var_arg);
  278.          else
  279.              printf ("%s_arg", opt->var_arg);
  280.  
  281.         printf (";\t/* %s", opt->desc);
  282.          
  283.                 if (opt->default_given)
  284.                   {
  285.                     if (opt->type == ARG_STRING)
  286.                       printf (" (default='%s')", opt->default_string);
  287.                     else
  288.                       printf (" (default=%.0f)", opt->default_num);
  289.                   }
  290.  
  291.         if (opt->type == ARG_FLAG)
  292.                   {
  293.                     if (opt->flagstat)
  294.                       printf (" (default=on)");
  295.                     else    
  296.                       printf (" (default=off)");
  297.                   }
  298.  
  299.         printf (".  */\n");
  300.     }
  301.  
  302.   printf ("\n");
  303.  
  304.   foropt
  305.     if (opt->type != ARG_NO) {
  306.         switch (opt->type) {
  307.         case ARG_FLAG:
  308.         case ARG_STRING:
  309.         case ARG_INT:
  310.         case ARG_SHORT:
  311.         case ARG_LONG:
  312.         case ARG_FLOAT:
  313.         case ARG_DOUBLE:
  314.         case ARG_LONGDOUBLE:
  315.         case ARG_LONGLONG: break;
  316.         default:
  317.                   fprintf (stderr, "gengetopt: bug found in %s:%d!!\n",
  318.                            __FILE__, __LINE__);
  319.                   abort ();
  320.         }
  321.                 indent ();
  322.         printf ("int %s_given ;\t/* Whether %s was given.  */\n",
  323.             opt->var_arg, opt->long_opt);
  324.     } else {
  325.       /* for NO_ARG options we simply create a "given" */
  326.       indent ();
  327.       printf ("int %s_given ;\t/* Whether %s was given.  */\n",
  328.               opt->var_arg, opt->long_opt);
  329.     }
  330.  
  331.   /* now print unamed options */
  332.   if ( unamed_options )
  333.     {
  334.       printf ("\n");
  335.       indent ();
  336.       printf ("char **inputs ; /* unamed options */\n") ;
  337.       indent ();
  338.       printf ("unsigned inputs_num ; /* unamed options number */\n") ;
  339.     }
  340.  
  341.   printf ("} ;\n\n" ) ;
  342.  
  343.   printf ("int %s (int argc, char * const *argv, struct %s *%s);\n\n", 
  344.           parser_function_name, ARGS_STRUCT_NAME, ARGS_STRUCT);
  345.  
  346.   printf ("void %s_print_help(void);\n", parser_function_name);
  347.   printf ("void %s_print_version(void);\n\n", parser_function_name);
  348.  
  349.   printf ("#ifdef __cplusplus\n");
  350.   printf ("}\n");
  351.   printf ("#endif /* __cplusplus */\n");
  352.  
  353.   printf ("#endif /* _%s_%s */\n", filename_canonized, header_ext);
  354.  
  355.   free (filename_canonized); // it's no longer useful
  356.  
  357.   fclose (output_file) ;
  358.  
  359.   /* ****************************************************** */
  360.   /* ********************************************** C FILE  */
  361.   /* ****************************************************** */
  362.  
  363.   tab_indentation = 0 ;
  364.  
  365.   output_file = open_outputfile (c_filename);
  366.  
  367.   printf (""
  368. "/*\n"
  369. "  File autogenerated by gengetopt version %s  \n", VERSION) ; 
  370.  
  371.   if ( comment )
  372.     {
  373.       i = 0 ;
  374.       for ( ; (comment_string = comment[i]) != NULL ; ++i ) 
  375.         printf ("  %s\n", comment_string );
  376.     }
  377.  
  378.   printf 
  379.     ("\n"
  380.      "  The developers of gengetopt consider the fixed text that goes in all\n"
  381.      "  gengetopt output files to be in the public domain:\n"
  382.      "  we make no copyright claims on it.\n");
  383.  
  384.   printf ("*/\n"
  385. "\n"
  386. "\n"
  387. "#include <stdio.h>\n"
  388. "#include <stdlib.h>\n"
  389. "#include <string.h>\n"
  390. "/* If we use autoconf.  */\n"
  391. "#ifdef HAVE_CONFIG_H\n"
  392. "#include \"config.h\"\n"
  393. "#endif\n"
  394. "/* Check for configure's getopt check result.  */\n"
  395. "#ifndef HAVE_GETOPT_LONG\n"
  396. "#include \"getopt.h\"\n"
  397. "#else\n"
  398. "#include <getopt.h>\n"
  399. "#endif\n"
  400. "\n"
  401. "#ifndef HAVE_STRDUP\n"
  402. "#define strdup gengetopt_strdup\n"
  403. "#endif /* HAVE_STRDUP */\n\n"
  404. "#include \"%s\"\n"
  405. "\n",
  406. header_filename);
  407.  
  408.   printf ("\n"
  409. "void\n"
  410. "%s_print_version (void)\n"
  411. "{\n"
  412. "  printf (\"%%s %%s\\n\", PACKAGE, VERSION);\n"
  413. "}\n"
  414. "\n"
  415. "void\n"
  416. "%s_print_help (void)\n"
  417. "{\n"
  418. "  %s_print_version ();\n", 
  419.           parser_function_name, parser_function_name, parser_function_name);
  420.   printf ("  printf(\"\\n\"\n");
  421.   if (gengetopt_purpose != NULL) {
  422.     char *ptr;
  423.     ptr = gengetopt_purpose;
  424.     printf (
  425. "\"Purpose:\\n\"\n"
  426. "\"  ");
  427.     for (; *ptr!='\0'; ptr++) {
  428.       if (*ptr == '\n') {
  429.     printf("\\n\"\n\"  ");
  430.       } else {
  431.     printf("%c", *ptr);
  432.       }
  433.     }
  434.     printf (""
  435. "\\n\"\n"
  436. "\"\\n\"\n");
  437.   }
  438.   printf ("\"Usage: %%s ");
  439.  
  440.  
  441.  
  442.   /* ****************************************************** */
  443.   /* ********************************************** OPTIONS */
  444.   /* ****************************************************** */
  445.  
  446.   if ( long_help )
  447.     {
  448.       foropt
  449.     if (opt->required) /* required options */
  450.         switch (opt->type) {
  451.         case ARG_INT:
  452.         case ARG_SHORT:
  453.         case ARG_LONG:
  454.         case ARG_FLOAT:
  455.         case ARG_DOUBLE:
  456.         case ARG_LONGDOUBLE:
  457.         case ARG_LONGLONG:
  458.         case ARG_STRING: 
  459.             if (opt->short_opt)
  460.             {
  461.                 printf ("-%c%s|", opt->short_opt, arg_names[opt->type]);
  462.             }
  463.             printf ("--%s=%s ", opt->long_opt, arg_names[opt->type]);
  464.            break;
  465.         default: fprintf (stderr, "gengetopt: bug found in %s:%d!!\n",
  466.                   __FILE__, __LINE__);
  467.                  abort ();
  468.         }
  469.   foropt
  470.     if (!opt->required)
  471.         switch (opt->type) {
  472.         case ARG_NO:
  473.         case ARG_FLAG: 
  474.             printf ("[");
  475.             if (opt->short_opt)
  476.             {
  477.               printf ("-%c|", opt->short_opt);
  478.             }
  479.             printf ("--%s] ", opt->long_opt);
  480.             break;
  481.         case ARG_INT:
  482.         case ARG_SHORT:
  483.         case ARG_LONG:
  484.         case ARG_FLOAT:
  485.         case ARG_DOUBLE:
  486.         case ARG_LONGDOUBLE:
  487.         case ARG_LONGLONG:
  488.         case ARG_STRING: 
  489.             if (opt->short_opt)
  490.             {
  491.                 printf ("-%c%s|", opt->short_opt, arg_names[opt->type]);
  492.            }
  493.            printf ("--%s=%s ", opt->long_opt, arg_names[opt->type]);
  494.            break;
  495.         default: fprintf (stderr, "gengetopt: bug found in %s:%d!!\n",
  496.                   __FILE__, __LINE__);
  497.                  abort ();
  498.         }
  499.   } else { /* if not long help we generate it as GNU standards */
  500.     printf ("[OPTIONS]...");    
  501.   }
  502.  
  503.   if ( unamed_options )
  504.       printf (" [FILES]...");
  505.  
  506.   printf ("\\n\", PACKAGE);\n");
  507.   /* calculate columns */
  508.   max_long = max_short = 0;
  509.   foropt {
  510.     w = 3 + strlen (opt->long_opt);
  511.     if (opt->type == ARG_FLAG || opt->type == ARG_NO)
  512.     {
  513.         if (w > max_long) max_long = w;
  514.         if (2 > max_short) max_short = 2;
  515.     }
  516.     else
  517.     {
  518.         w += strlen (arg_names[opt->type]);
  519.         if (w > max_long) max_long = w;
  520.         w = (3 + strlen (arg_names[opt->type]));
  521.         if (w > max_short) max_short = w;
  522.     }
  523.   }
  524.   /* print justified options */
  525.   foropt
  526.   {
  527.     printf ("  printf(\"");
  528.     if (opt->type == ARG_FLAG || opt->type == ARG_NO)
  529.     {
  530.       if (opt->short_opt) printf ("   -%c", opt->short_opt);
  531.       else                printf ("     ");
  532.       for (w = 2; w < max_short; w++) printf (" ");
  533.       printf ("  --%s", opt->long_opt);
  534.       for (w = 2+strlen(opt->long_opt); w < max_long; w++)
  535.     printf (" ");
  536.       printf ("  %s", opt->desc);
  537.       if (opt->type == ARG_FLAG)
  538.       {
  539.     if (opt->flagstat)
  540.       printf (" (default=on)");
  541.     else
  542.       printf (" (default=off)");
  543.       }
  544.       printf ("\\n\");\n");
  545.     }
  546.     else
  547.     {
  548.       if (opt->short_opt)
  549.     printf ("   -%c%s", opt->short_opt, arg_names[opt->type]);
  550.       else
  551.       {
  552.     int type_len = strlen(arg_names[opt->type]);
  553.  
  554.     printf ("      ");
  555.     for (w = 1; w < type_len; w++) printf (" ");
  556.       }
  557.       for (w = 2+strlen(arg_names[opt->type]); w < max_short; w++)
  558.     printf (" ");
  559.       printf ("  --%s=%s", opt->long_opt, arg_names[opt->type]);
  560.       for (w = 3+strlen(opt->long_opt)+
  561.          strlen(arg_names[opt->type]); w < max_long; w++)
  562.     printf (" ");
  563.       printf ("  %s", opt->desc);
  564.       if (opt->default_given)
  565.         {
  566.           if (opt->type == ARG_STRING)
  567.             printf (" (default='%s')", opt->default_string);
  568.           else
  569.             printf (" (default=%.0f)", opt->default_num);
  570.         }
  571.       printf ("\\n\");\n");
  572.     }
  573.   }
  574.   printf ("}\n\n\n");
  575.  
  576.   if (! generate_strdup)
  577.     {
  578.       foropt
  579.     if (opt->type == ARG_STRING) {
  580.           generate_strdup = 1;
  581.           break;
  582.     }
  583.     }
  584.  
  585.   if (generate_strdup) 
  586.     {
  587.       for (i = 1; i <= gengetopt_strdup_text_length; ++i)
  588.         printf ("%s\n", gengetopt_strdup_text[i]);
  589.       printf ("\n");
  590.     }
  591.   
  592.   printf (
  593. "int\n"
  594. "%s (int argc, char * const *argv, struct %s *%s)\n"
  595. "{\n"
  596. "  int c;\t/* Character of the parsed option.  */\n"
  597. "  int missing_required_options = 0;\t\n"
  598. "\n", parser_function_name, ARGS_STRUCT_NAME, ARGS_STRUCT);
  599.  
  600. inc_indent ();
  601.  
  602.   /* now we initialize "given" fields */
  603.   foropt
  604.     {
  605.       indent ();
  606.       printf ("%s->%s_given = 0 ;\n",
  607.           ARGS_STRUCT, opt->var_arg);
  608.     }
  609.  
  610.   printf ("#define clear_args() { \\\n");
  611.  
  612.     /* now we initialize fields */
  613.   foropt
  614.     if (opt->type == ARG_STRING)
  615.           {
  616.             indent ();
  617.             if (opt->default_given)
  618.               printf ("%s->%s_arg = strdup(\"%s\") ;\\\n",
  619.                       ARGS_STRUCT, opt->var_arg, opt->default_string);
  620.             else
  621.               printf ("%s->%s_arg = NULL; \\\n",
  622.                       ARGS_STRUCT, opt->var_arg);
  623.           }
  624.         else if (opt->type == ARG_FLAG)
  625.           {
  626.             indent ();
  627.             printf ("%s->%s_flag", ARGS_STRUCT, opt->var_arg);
  628.             printf (" = %d;\\\n", opt->flagstat);
  629.           }
  630.         else if (opt->type != ARG_NO && opt->default_given)
  631.           {
  632.             indent ();
  633.             printf ("%s->%s_arg", ARGS_STRUCT, opt->var_arg);
  634.             printf (" = %.0f;\\\n", opt->default_num);
  635.           }
  636.  
  637.   printf ("}\n\n") ;
  638.  
  639.   indent ();
  640.   printf ("clear_args();\n") ;
  641.  
  642.   /* now initialize unamed options */
  643.   if ( unamed_options )
  644.     {
  645.       printf ("\n");
  646.       indent ();
  647.       printf ("%s->inputs = NULL;\n", ARGS_STRUCT) ;
  648.       indent ();
  649.       printf ("%s->inputs_num = 0;\n", ARGS_STRUCT) ;
  650.     }
  651.  
  652.   printf ("\n");
  653.  
  654.   /* the following generated instructions are useful, when the
  655.      parser is called more than once. 
  656.      Suggested by Eric H Kinzie <ekinzie@cmf.nrl.navy.mil> */
  657.   indent ();
  658.   printf ("optarg = 0;\n");
  659.   indent ();
  660.   printf ("optind = 1;\n");
  661.   indent ();
  662.   printf ("opterr = 1;\n");
  663.   indent ();
  664.   printf ("optopt = '?';\n");
  665.  
  666.   printf ("\n");
  667.  
  668.   indent ();
  669.   printf ("while (1)\n");
  670.   inc_indent ();
  671.   indent ();
  672.   printf ("{\n");
  673.   inc_indent ();
  674.   indent ();
  675.   printf ("int option_index = 0;\n");
  676.   indent ();
  677.   printf ("static struct option long_options[] = {\n");
  678.  
  679.   inc_indent ();
  680.  
  681.   foropt
  682.     {
  683.       indent ();
  684.       printf ("{ \"%s\",\t%d, NULL, ", opt->long_opt,
  685.                   (opt->type == ARG_NO || opt->type == ARG_FLAG ? 0 : 1));
  686.       if (opt->short_opt) printf ("\'%c\'", opt->short_opt);
  687.       else printf ("0");
  688.       printf (" },\n");
  689.     }
  690.  
  691.   indent ();
  692.   printf ("{ NULL,\t0, NULL, 0 }\n");
  693.  
  694.   dec_indent ();
  695.   indent ();
  696.   printf ("};\n\n");
  697.  
  698.   indent ();
  699.   printf ("c = getopt_long (argc, argv, \"");
  700.  
  701.   foropt
  702.     if (opt->short_opt)
  703.         printf ("%c%s", opt->short_opt,
  704.                 (opt->type == ARG_NO || opt->type == ARG_FLAG ? "" : ":"));
  705.  
  706.   printf ("\", long_options, &option_index);\n\n");
  707.  
  708.   indent ();
  709.   printf ("if (c == -1) break;\t/* Exit from `while (1)' loop.  */\n\n");
  710.  
  711.   indent ();
  712.   printf ("switch (c)\n");
  713.   inc_indent ();
  714.   indent ();
  715.   printf ("{");
  716.  
  717.   if (! no_handle_help)
  718.     {
  719.       printf ("\n");
  720.       indent ();
  721.       printf ("case 'h':\t/* Print help and exit.  */\n");
  722.       inc_indent ();
  723.       indent ();
  724.       
  725.       printf ("clear_args ();\n");
  726.       indent ();
  727.       printf ("%s_print_help ();\n", parser_function_name);
  728.       indent ();
  729.       printf ("exit (EXIT_SUCCESS);\n");
  730.  
  731.       dec_indent ();
  732.     }
  733.  
  734.   if (! no_handle_version)
  735.     {
  736.       printf ("\n");
  737.       indent ();
  738.       printf ("case 'V':\t/* Print version and exit.  */\n");
  739.       inc_indent ();
  740.       indent ();
  741.       printf ("clear_args ();\n");
  742.       indent ();
  743.       printf ("%s_print_version ();\n", parser_function_name);
  744.       indent ();
  745.       printf ("exit (EXIT_SUCCESS);\n");
  746.       dec_indent ();
  747.     }
  748.  
  749.   /* ****************************************************** */
  750.   /* ********************************************* GENERATE */
  751.   /* ****************************************************** */
  752.  
  753.  
  754.   foropt {
  755.     if (
  756.         (opt->short_opt == 'h' && ! no_handle_help) || 
  757.         (opt->short_opt == 'V' && ! no_handle_version)
  758.         ) 
  759.       continue;
  760.  
  761.     printf ("\n");
  762.     indent ();
  763.     if (opt->short_opt)
  764.     {
  765.         printf ("case '%c':\t/* %s.  */\n", opt->short_opt,
  766.                 opt->desc);
  767.         inc_indent ();
  768.         do_check_option_given (opt);
  769.         indent ();
  770.  
  771.         if (opt->short_opt == 'h' || opt->short_opt == 'V')
  772.           printf ("return 0;\n");
  773.         else
  774.           printf ("break;\n");
  775.  
  776.         dec_indent ();
  777.     }
  778.   }
  779.  
  780.   printf ("\n");
  781.   indent ();
  782.   printf ("case 0:\t/* Long option with no short option */\n");
  783.   inc_indent();
  784.   foropt 
  785.       if (!opt->short_opt)
  786.       {
  787.           indent();
  788.           printf ("/* %s.  */\n", opt->desc);
  789.           indent();
  790.           printf ("%sif (strcmp (long_options[option_index].name, "
  791.                   "\"%s\") == 0)\n",
  792.                   ((first_time == 0) ? "else " : ""),
  793.                   opt->long_opt);
  794.           first_time = 0;
  795.           indent();
  796.           printf ("{\n");
  797.           inc_indent();
  798.           do_check_option_given (opt);
  799.           indent ();
  800.           printf ("break;\n");
  801.           dec_indent();
  802.           indent ();
  803.           printf ("}\n");        
  804.       }
  805.   dec_indent ();
  806.  
  807.   printf ("\n");
  808.   indent ();
  809.   printf ("case '?':\t/* Invalid option.  */\n");
  810.   inc_indent ();
  811.   indent ();
  812.   printf ("/* `getopt_long' already printed an error message.  */\n");
  813.   indent ();
  814.   generate_error_handle ();
  815.   printf ("\n");
  816.   
  817.   dec_indent ();
  818.   indent ();
  819.   printf ("default:\t/* bug: option not considered.  */\n");
  820.   inc_indent ();
  821.   indent ();
  822.   printf ("fprintf (stderr, \"%%s: option unknown: %%c\\n\", PACKAGE, c);\n");
  823.   indent ();
  824.   printf ("abort ();\n");
  825.   dec_indent ();
  826.   indent ();
  827.   printf ("} /* switch */\n");
  828.   dec_indent ();
  829.   dec_indent ();
  830.  
  831.   indent ();
  832.   printf ("} /* while */\n\n");
  833.   dec_indent ();
  834.  
  835.   /* write test for required options */
  836.   foropt
  837.     if ( opt->required )
  838.       {
  839.         indent ();
  840.         printf ("if (! %s->%s_given)\n", ARGS_STRUCT, opt->var_arg);
  841.         inc_indent ();
  842.         indent ();
  843.         printf ("{\n"); 
  844.         inc_indent ();
  845.         indent ();
  846.         if (opt->short_opt)
  847.             printf ("fprintf (stderr, \"%%s: `--%s' (`-%c') option required\\n\", PACKAGE);\n", opt->long_opt, opt->short_opt);
  848.         else
  849.             printf ("fprintf (stderr, \"%%s: `--%s' option required\\n\", PACKAGE);\n", opt->long_opt);
  850.         indent ();
  851.         printf ("missing_required_options = 1;\n");
  852.         dec_indent ();
  853.         indent ();
  854.         printf ("}\n\n");
  855.         dec_indent (); 
  856.       }
  857.  
  858.   /* let's see if everything went fine*/
  859.   indent ();
  860.   printf ("if ( missing_required_options )\n");
  861.   inc_indent ();
  862.   indent ();
  863.   generate_error_handle ();
  864.   printf ("\n");
  865.   dec_indent ();
  866.  
  867.   /* now handle unamed options */
  868.   if ( unamed_options )
  869.     {
  870.       indent (); 
  871.       printf ("if (optind < argc)\n");
  872.       inc_indent ();
  873.       indent ();
  874.       printf ("{\n");
  875.       
  876.       inc_indent ();
  877.       indent ();
  878.       printf ("int i = 0 ;\n\n");
  879.  
  880.       indent ();
  881.       printf ("%s->inputs_num = argc - optind ;\n", ARGS_STRUCT);
  882.       indent ();
  883.       printf ("%s->inputs = \n", ARGS_STRUCT);
  884.       indent ();
  885.       printf ("  (char **)(malloc ((%s->inputs_num)*sizeof(char *))) ;\n", 
  886.               ARGS_STRUCT);
  887.  
  888.       indent ();
  889.       printf ("while (optind < argc)\n");
  890.  
  891.       inc_indent ();
  892.       indent ();
  893.       printf ("%s->inputs[ i++ ] = strdup (argv[optind++]) ; \n", 
  894.               ARGS_STRUCT);
  895.  
  896.       dec_indent ();
  897.       dec_indent ();
  898.       indent ();
  899.       printf ("}\n");
  900.       dec_indent (); 
  901.     }
  902.  
  903.   printf ("\n");
  904.   indent ();
  905.   printf ("return 0;\n");
  906.   printf ("}\n");
  907.  
  908.   fclose (output_file) ;
  909.  
  910.   return 0;
  911. }
  912.  
  913. void inc_indent()
  914. {
  915.   tab_indentation += TAB_LEN ;
  916. }
  917.  
  918. void dec_indent()
  919. {
  920.   tab_indentation -= TAB_LEN ;
  921. }
  922.  
  923. void indent()
  924. {
  925.   register int i ;
  926.   
  927.   for ( i = 1 ; i <= tab_indentation ; ++i )
  928.     printf (" ");
  929. }
  930.  
  931. void
  932. check_option_given( char *var_arg, char *long_opt, char short_opt )
  933. {
  934.   indent ();
  935.   printf ("if (%s->%s_given)\n", ARGS_STRUCT, var_arg);
  936.   inc_indent ();
  937.   indent ();
  938.   printf ("{\n");
  939.   inc_indent ();
  940.   indent ();
  941.   if (short_opt)
  942.       printf ("fprintf (stderr, \"%%s: `--%s' (`-%c') option given more than once\\n\", PACKAGE);\n", long_opt, short_opt);
  943.   else 
  944.       printf ("fprintf (stderr, \"%%s: `--%s' option given more than once\\n\", PACKAGE);\n", long_opt);
  945.   indent ();
  946.   printf ("clear_args ();\n");
  947.   indent ();
  948.   generate_error_handle ();
  949.   dec_indent ();
  950.   indent ();
  951.   printf ("}\n");
  952.   dec_indent ();
  953.   indent ();
  954.   printf ("%s->%s_given = 1;\n", ARGS_STRUCT, var_arg);
  955. }
  956.  
  957. void
  958. generate_error_handle()
  959. {
  960.   if (handle_error)
  961.     printf ("exit (EXIT_FAILURE);\n");
  962.   else
  963.     printf ("return (EXIT_FAILURE);\n");
  964. }
  965.  
  966. /*
  967.   return a copy of the string passed after canonizing it (i.e. '-' and
  968.   '.' are transformed in '_'.
  969. */
  970. char *
  971. canonize_names (char *name)
  972. {
  973.   char *pvar;
  974.   char *p;
  975.  
  976.   pvar = strdup (name);
  977.  
  978.   for (p = pvar; *p; ++p)
  979.     if (*p == '.' || *p == '-') *p = '_';
  980.  
  981.   return pvar;
  982. }
  983.